/**
 * 
 */
package org.rcgwt.client.ui.grid.reflect;

import java.util.HashSet;
import java.util.Set;

import org.rcgwt.client.model.BeanProperty;
import org.rcgwt.client.model.Reflected;
import org.rcgwt.client.model.BeanProperty.Access;
import org.rcgwt.client.ui.grid.event.IModelChangeState.ChangeStateType;
import org.rcgwt.client.ui.grid.internal.ModelChangeState;
import org.rcgwt.client.ui.grid.model.IEditableDataModel;

import com.google.gwt.event.logical.shared.ValueChangeEvent;

/**
 * 
 * 
 * @author Matthieu ROBERT
 * 
 */
public class EditableReflectedDataModel<T> extends ReflectedDataModel<T>
        implements IEditableDataModel {

    private final Set<String> setters;

    public EditableReflectedDataModel(Class<T> modelClass) {
        super(modelClass);

        setters = new HashSet<String>(beanProperties.length);

        for (BeanProperty beanProperty : beanProperties) {
            if (beanProperty.getAccess() == Access.READ_ONLY) {
                continue;
            }

            setters.add(beanProperty.getName());
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.rcgwt.client.ui.grid.model.IEditableDataModel#isCellEditable(int,
     * int)
     */
    @Override
    public boolean isCellEditable(int rowIndex, String columnName) {
        if ((columnName != null) && (setters != null)) {
            return setters.contains(columnName);
        }
        return false;
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, String columnName) {
        if (isCellEditable(rowIndex, columnName) == false) {
            return;
        }

        if (rowIndex < getRowCount()) {
            Reflected<T> object = getRowValueAt(rowIndex);
            object.set(columnName, aValue);

            ValueChangeEvent.fire(this, new ModelChangeState(rowIndex, 1, 0,
                    ChangeStateType.UPDATE));
        }

    }
}
